package com.hdlang.android.v2.patch.plugin;

import com.hdlang.android.v2.patch.plugin.utils.AsmUtils;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AdviceAdapter;

public class RobustMethodAdapter extends AdviceAdapter {
    private String className;

    /**
     * Constructs a new {@link AdviceAdapter}.
     *
     * @param api           the ASM API version implemented by this visitor. Must be one of {@link
     *                      Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
     * @param methodVisitor the method visitor to which this adapter delegates calls.
     * @param access        the method's access flags (see {@link Opcodes}).
     * @param name          the method's name.
     * @param descriptor    the method's descriptor (see {@link Type Type}).
     */
    public RobustMethodAdapter(String className, int api, MethodVisitor methodVisitor, int access, String name, String descriptor) {
        super(api, methodVisitor, access, name, descriptor);
        this.className = className;
    }

    @Override
    protected void onMethodEnter() {
        super.onMethodEnter();
        final String name = getName();
        if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
            final boolean isStatic = (getAccess() | Opcodes.ACC_STATIC) != 0;
            final Type returnType = Type.getReturnType(methodDesc);
            AsmUtils.createInsertCode(
                    this,
                    className,
                    getArgumentTypes(),
                    returnType,
                    isStatic,
                    (isStatic ? "static|" : "") + className + "[" + getName() + "(" + methodDesc + ")]"
            );
        }
    }
}
